package cn.picclife.mwx.manager.util.uniqueseq;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.picclife.mwx.common.core.util.SpringContextUtil;
import cn.picclife.mwx.manager.sys.model.po.UniqueTable;
import cn.picclife.mwx.manager.sys.service.UniqueTableService;


/**
 * 需要使用自己的链接，不能使用业务类的链接。
 * <p>
 * 用于获取
 * 
 * @author cn_shuai
 * 
 */
class UniqueSeqInfo {
	private final static Logger logger = LoggerFactory.getLogger(UniqueSeqInfo.class);

	private static UniqueSeqInfo AUNIQUESEQ = null;
	private static Map<String, UniqueObj> UNIQUESEQ = new HashMap<String, UniqueObj>();
	// 递增量
	private final static int INCREMENTAL_CHANGE = 1;

	private UniqueSeqInfo() {

	}

	/**
	 * 得到数据库操作实例
	 * 
	 * @return
	 */
	public synchronized static UniqueSeqInfo getInstance() {
		if (AUNIQUESEQ == null) {
			AUNIQUESEQ = new UniqueSeqInfo();
		}
		return AUNIQUESEQ;
	}

	/**
	 * 根据序列名称查找序列号。
	 * 
	 * @param seqName
	 * @return
	 */
	public synchronized Long getUniqueSeq(String seqName) {
		// 如果列表中不存在该序列值，则去创建序列值
		if (!UNIQUESEQ.containsKey(seqName)) {
			UNIQUESEQ.put(seqName, this.createUniqueSeq(seqName));
		}
		// 从列表中取出相应的序列
		// 如果现在的值大于等于分配的最大值，则再创建一次
		if (UNIQUESEQ.get(seqName).getNow() >= UNIQUESEQ.get(seqName).getMax()) {
			UNIQUESEQ.put(seqName, this.createUniqueSeq(seqName));
		}
		UNIQUESEQ.get(seqName).setNow(UNIQUESEQ.get(seqName).getNow() + 1);
		return UNIQUESEQ.get(seqName).getNow();

	}

	/**
	 * 根据序列名称、表名称查找序列号。
	 * 
	 * @param seqName
	 * @return
	 */
	public synchronized Long getUniqueSeq(String seqName, String tableName) {
		// 如果列表中不存在该序列值，则去创建序列值
		if (!UNIQUESEQ.containsKey(seqName + tableName)) {
			UNIQUESEQ.put(seqName + tableName, this.createUniqueSeq(seqName, tableName));
		}
		// 从列表中取出相应的序列
		// 如果现在的值大于等于分配的最大值，则再创建一次
		if (UNIQUESEQ.get(seqName + tableName).getNow() >= UNIQUESEQ.get(seqName + tableName).getMax()) {
			UNIQUESEQ.put(seqName + tableName, this.createUniqueSeq(seqName, tableName));
		}
		UNIQUESEQ.get(seqName + tableName).setNow(UNIQUESEQ.get(seqName + tableName).getNow() + 1);
		return UNIQUESEQ.get(seqName + tableName).getNow();
	}

	/**
	 * 查询数据库中当前的code，并且生成新的code。
	 * 
	 * @param seqName
	 * @return
	 */
	private synchronized UniqueObj createUniqueSeq(String seqName) {
		long code = -1;
		UniqueObj uniqueObj = new UniqueObj();
		UniqueTable record = new UniqueTable();
		record.setName(seqName);
		UniqueTableService uniqueTableService = SpringContextUtil.getBean("uniqueTableService", UniqueTableService.class);
		
		UniqueTable uniqueTable = uniqueTableService.selectBySeqName(record);
		if (uniqueTable != null) {
			code = uniqueTable.getCode().longValue();
		}
		if (code == -1) {
			record.setCode(new BigDecimal(1));
			uniqueTableService.insertSelective(record);
			code = 1;
			logger.debug("未定义[" + seqName + "]主键，系统已自动添加。");

		}

		record.setCode(new BigDecimal(code + INCREMENTAL_CHANGE));
		uniqueTableService.updateUnique(record);
		// 设置现在的值
		uniqueObj.setNow(code);
		// 设置最大值
		uniqueObj.setMax(code + INCREMENTAL_CHANGE);
		// 设置本次开始值
		uniqueObj.setStart(code);
		return uniqueObj;
	}

	/**
	 * 根据seqName、tableName 查询数据库中当前的code，并且生成新的code。
	 * 
	 * @param seqName
	 * @return
	 */
	private synchronized UniqueObj createUniqueSeq(String seqName, String tableName) {
		long code = -1;
		UniqueObj uniqueObj = new UniqueObj();
		UniqueTable record = new UniqueTable();
		record.setName(seqName);
		record.setSpace1(tableName);
		
		UniqueTableService uniqueTableService = (UniqueTableService)SpringContextUtil.getBean("uniqueTableService", UniqueTableService.class);
		UniqueTable uniqueTable = uniqueTableService.selectBySeqNameAndTable(record);
		if (uniqueTable != null) {
			code = uniqueTable.getCode().longValue();
		}
		if (code == -1) {
			record.setCode(new BigDecimal(1));
			uniqueTableService.insertSelective(record);
			code = 1;
			logger.debug("未定义[" + seqName + "," + tableName + "]主键，系统已自动添加。");

		}

		record.setCode(new BigDecimal(code + INCREMENTAL_CHANGE));
		uniqueTableService.updateUnique(record);
		// 设置现在的值
		uniqueObj.setNow(code);
		// 设置最大值
		uniqueObj.setMax(code + INCREMENTAL_CHANGE);
		// 设置本次开始值
		uniqueObj.setStart(code);
		return uniqueObj;
	}
}
